#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Wave Relay
# Copyright (C) 2010 Yakovlev Vladimir [nvbn.rm@gmail.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import pylast
import json
from PyQt4 import QtCore
import mediawidgets
import thread

class LastSearch:
    """Lastfm search class"""
    username = None
    password_hash = None
    API_KEY = "10fed419f67aebbadecb729de799b851"
    API_SECRET = "19c677fc2c3463a4c9bd26ed4da71756"

    def __init__(self, username = None, password = None):
        """Init class

        Keyword arguments:
        username -- String
        password -- String

        Returns: None

        """
        if username != None:
            self.username =username
        if password != None:
            self.password_hash = pylast.md5(password)
        self.network = pylast.get_lastfm_network(api_key = self.API_KEY, api_secret = self.API_SECRET, username = self.username, password_hash = self.password_hash)

    def searchArtist(self, query):
        """Search for artists in lastfm

        Keyword arguments:
        query -- String

        Returns: *pylast.Artist

        """
        return(self.network.search_for_artist(query).get_next_page())

    def searchAlbum(self, query = None, artist = None):
        """Search for albums in lastfm

        Keyword arguments:
        query -- String
        artist -- pylast.Artist

        Returns: *pylast.Album

        """
        if artist:
            albums = artist.get_top_albums()
        elif query:
            albums =  self.network.search_for_album(query).get_next_page()
        return(albums)

    def searchTrack(self, query = None, album = None):
        """Search for songs in lastfm

        Keyword arguments:
        query -- String
        album -- pylast.Album

        Returns: *pylast.Track

        """
        if album:
            tracks = album.get_tracks()
        else:
            tracks = self.network.search_for_track('', query).get_next_page()
            tracks += self.network.search_for_track(query, '').get_next_page()
        return(tracks)

    def searchGenre(self, query):
        """Search for genres in lastfm

        Keyword arguments:
        query -- String

        Returns: *pylast.Genre

        """
        return(self.network.search_for_tag(query).get_next_page())

class Search:
    """Search class"""
    history = []

    def __init__(self, parent):
        """Init class

        Keyword arguments:
        parent -- parent class

        Returns: None

        """
        self.parent = parent

    def _get_type(self):
        """Get type of search"""
        return(self.parent.widget.searchType.currentIndex())

    def _set_type(self, type):
        """Set type of search

        Keyword arguments:
        type -- Int

        Returns: Boolean

        """
        self.parent.widget.searchType.setCurrentIndex(type)
        self.parent.searchlist.type = type
        return(True)

    def _search_artist(self, query):
        """Search for artists

        Keyword arguments:
        query -- String

        Returns: None

        """
        artists = self.parent.lastfm.searchArtist(query)

        for artist in artists:
            self.parent.searchlist.append(mediawidgets.Artist(artist), 0)

    def _search_album(self, query):
        """Search for albums

        Keyword arguments:
        query -- String

        Returns: None

        """
        albums = self.parent.lastfm.searchAlbum(query)
        for album in albums:
            self.parent.searchlist.append(mediawidgets.Album(album), 1)

    def _search_song(self, query):
        """Search for songs

        Keyword arguments:
        query -- String

        Returns: None

        """
        songs = self.parent.lastfm.searchTrack(query)
        for song in songs:
            self.parent.searchlist.append(mediawidgets.Song(song), 2)

    def _search_genre(self, query):
        """Search for genre

        Keyword arguments:
        query -- String

        Returns: None

        """
        genres = self.parent.lastfm.searchGenre(query)
        for genre in genres:
            self.parent.searchlist.append(mediawidgets.Genre(genre), 3)

    @QtCore.pyqtSlot()
    def click(self):
        """Parse widgets and expand clicked"""
        def action(sender, type):
            """Action for click on widget, runned in other thread

            Keyword arguments:
            type -- Int

            Returns: None

            """
            if type == 0:
                self._set_type(1)
                for album in sender.artist.get_top_albums():
                    self.parent.searchlist.append(mediawidgets.Album(album[0]), 1)
            elif type == 1:
                self._set_type(2)
                for track in sender.album.get_tracks():
                    self.parent.searchlist.append(mediawidgets.Song(track), 2)
            elif type == 2:
                self.parent.playlist.append(mediawidgets.Song(sender.song))
            elif type == 3:
                self._set_type(0)
                for artist in sender.genre.get_top_artists():
                    self.parent.searchlist.append(mediawidgets.Artist(artist[0]), 0)
                

        sender = self.parent.widget.searchResult.currentItem()
        type = self._get_type()
        type == 2 or self.parent.searchlist.clear()
        thread.start_new_thread(action, (sender, type, ))


    @QtCore.pyqtSlot()
    def back_history(self):
        """Back in search history"""
        vars = self.history[len(self.history)-2:][0]
        del self.history[len(self.history)-2:][1]
        self._set_type(vars[0])
        self.parent.widget.searchEdit.setText(vars[1])
        return(self.find(True, *vars))

    @QtCore.pyqtSlot()
    def save_last(self, file):
        """Save last search to file

        Keyword arguments:
        file -- String -- path

        Returns: None

        """
        file = open(file, 'w')
        file.write(json.dumps(self.history[len(self.history)-1]))
        file.close()

    @QtCore.pyqtSlot()
    def load(self, file):
        """Load search values from file

        Keyword arguments:
        file -- String -- path

        Returns: None

        """
        file = open(file, 'r')
        data = json.loads(file.read())
        file.close()
        self._set_type(data[0])
        self.parent.widget.searchEdit.setText(data[1])
        self.find(False, *data)

    @QtCore.pyqtSlot()
    def find(self, back = False, type = None, query = None):
        """Parse widgets and run search

        Keyword arguments:
        back -- Boolean
        type -- Int
        query -- String

        Returns: None

        """
        def action(self, query, type):
            if type == 0:
                self._search_artist(query)
            elif type == 1:
                self._search_album(query)
            elif type == 2:
                self._search_song(query)
            elif type == 3:
                self._search_genre(query)
        if not back:
            type = self._get_type()
            query = unicode(self.parent.widget.searchEdit.text())
            self.history.append((type, query,))
        self.parent.widget.backList.setEnabled(len(self.history) >=2)

        self.parent.searchlist.type = type
        self.parent.searchlist.clear()
        thread.start_new_thread(action, (self, query, type, ))





